package com.algorithm.ch1.lzr.string;

/**
 * 给定一个 32 位有符号整数，将整数中的数字进行反转。
 * <p>
 * 示例 1:
 * 输入: 123
 * 输出: 321
 * <p>
 * 示例 2:
 * 输入: -123
 * 输出: -321
 * <p>
 * 示例 3:
 * 输入: 120
 * 输出: 21
 * <p>
 * 假设我们的环境只能存储 32 位有符号整数, 其数值范围是 [−2^31,2^31−1] 根据这个假设，如果反转后的整数溢出, 则返回 0
 *
 * @author lzr
 * @date 2018/8/9
 */
public class Reverse {
    public static void main(String[] args) {
        int reverse = reverse(2147483647);
        System.out.print(reverse);
    }


    /**
     * 内存溢出：计算机中用二进制表示所有的信息, 这个符号的区别就看首位
     * 首位为0就是正的, 1就是负的 [正与负的区别也因此就在于取反加一]
     * Java 中的 int 总共就 32 位, 正数上限的情况首位也只能是 0, 其他位都可以是 1 (就是 2^31-1 的情况)
     * 但是如果正数过大了, 例如 2^31, 计算机不得不把首位变成 1, 变成负数
     * <p>
     * 2^31 - 1 = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647
     * 2^31 = (2^31 - 1) + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648
     *
     * 对于int类型,存在负数-2147483648(-2^31),(取反+1)或(取绝对值)后,还是负数,有整数溢出现象
     *
     * @param in
     * @return
     */
    public static int reverse(int in) {
        int abs = Math.abs(in);
        int out = 0;
        while (abs > 0) {
            if (out > Integer.MAX_VALUE / 10) {
                return 0;
            }
            out *= 10;
            out += abs % 10;
            abs /= 10;
        }
        if (in < 0) {
            out = -out;
        }
        return out;
    }

}
